{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 基于物品的协同过滤\n",
    "\n",
    "## 定义\n",
    "\n",
    "在一个推荐系统中，如果需要对A进行个性化推荐，可以首先寻找与 A 感兴趣的物品相似的物品，再将这些A感兴趣物品相似、而A没有听说过的物品推荐给A。这种方法称为基于物品的协同过滤算法。\n",
    "\n",
    "这个问题可以分为两步\n",
    "\n",
    "- 计算物品之间的相似度\n",
    "- 根据物品的相似度和用户的历史行为给用户生成推荐列表\n",
    "\n",
    "## 计算物品相似度\n",
    "\n",
    "基于物品的协同过滤算法是由亚马逊公司提出，描述为“Customers Who Bought This Item Also Bought”，《推荐系统实践》书中根据上述描述定义了物品相似度计算公式：\n",
    "\n",
    "$$w_{ij} = \\frac{|N(i) \\cap N(j)|}{N(i)}$$\n",
    "\n",
    "其中N(i)为喜欢物品i的用户的集合，同理N(j)为喜欢物品j的用户的集合。\n",
    "\n",
    "《推荐系统实践》中认为上述公式存在，如果物品j非常热门，会造成任何物品和j的相似度都很大的问题，从而提出了下述公式：\n",
    "\n",
    "$$w_{ij} = \\frac{|N(i) \\cap N(j)|}{\\sqrt{|N(i)||N(j)|}}$$\n",
    "\n",
    "此公式再分母中惩罚了物品j的权重，这样用来减轻热门物品和任何物品都相似的情况。\n",
    "\n",
    "这里面蕴涵着一个假设，就是每个用户的兴趣都局限在某几个方面，因此如果两个物品属于一个用户的兴趣列表，那么这两个物品可能就属于有限的几个领域，而如果两个物品属于很多用户的兴趣列表，那么它们就可能属于同一个领域，因而有很大的相似度。\n",
    "\n",
    "### 计算过程\n",
    "\n",
    "- 建立用户—物品倒排表\n",
    "\n",
    "- 建立稀疏矩阵C，然后对于每个用户，将他物品列表中两两在共现的物品在矩阵$C[i][j] += 1$\n",
    "\n",
    "## 物品推荐\n",
    "\n",
    "得到物品之间的相似度后，ItemCF算法会给用户推荐他感兴趣的物品最相似的K个物品。\n",
    "\n",
    "### 度量用户对物品感兴趣的程度\n",
    "\n",
    "在得到物品之间的相似度后，可以计算用户u对一个物品j的兴趣：\n",
    "\n",
    "$$p(u,j) = \\sum_{i \\in N(u) \\cap S(j, K)} w_{ji} r_{ui}$$\n",
    "\n",
    "这里N(u)是用户喜欢的物品的集合，S(j,K)是和物品j最相似的K个物品的集合，$w_{ji}$是物品j和i的相似度，$r_{ui}$是用户u对物品i的兴趣。（对于隐反馈数据集，如果用户u对物品i有过行为，即可令$r_{ui} = 1$。）该公式的含义是，和用户历史上感兴趣的物品越相似的物品，越有可能在用户的推荐列表中获得比较高的排名。\n",
    "\n",
    "## 算法中超参数K\n",
    "\n",
    "- 准确率和召回率：F推荐结果的精度也是不和K成正相关或者负相关的，因此选择合适的K对获得最高精度是非常重要的。\n",
    "\n",
    "- 流行度：和UserCF不同，随着K的增加，结果流行度会逐渐提高，但打到一定程度后不再变化\n",
    "\n",
    "- 覆盖率：K增加会降低系统的覆盖率。\n",
    "\n",
    "## 相似度公式优化\n",
    "\n",
    "活跃用户会对物品相似度计算产生干扰。如果一个图书采购员，购买了80w本书用于售卖，则这80w本书之间，两两产生了相似度。\n",
    "\n",
    "John S. Breese在论文中提出了一个称为IUF（Inverse User Frequence），即用户活跃度对数的倒数的参数，他也认为活跃用户对物品相似度的贡献应该小于不活跃的用户，他提出应该增加IUF参数来修正物品相似度的计算公式：\n",
    "\n",
    "$$w_{ij}= \\frac{\\sum_{u \\in N(i) \\cap N(j)} \\frac{1}{log(1+|N(u)|)}}{\\sqrt{|N(i)| |N(j)|}}$$\n",
    "\n",
    "但是，上述公式也只是对活跃用户做了一种软性的惩罚，但是对于过于活跃的用户（如上述图书采购员），为了避免相似度矩阵过于稠密，应直接忽略其邢确列表。\n",
    "\n",
    "**另：物品相似度归一化可提高准确率**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**IUF 参见John S. Breese、 David Heckerman和 Carl Kadie的“ Empirical Analysis of Predictive Algorithms for Collaborative\n",
    "Filtering”（Morgan Kaufmann Publishers ，1998）。**\n",
    "\n",
    "**注：本文档中数据和公式来自 项亮先生的《推荐系统实践》 一书，如有侵权，请联系[我](https://github.com/TobiahShaw/tensorflow_hello/issues)**"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
